﻿using DiLe.Mes.Application.Cloud.Statistics;
using DiLe.Mes.Application.Common;
using DiLe.Mes.Application.Common.Equipment;
using DiLe.Mes.Application.Common.Mould;
using DiLe.Mes.Application.Handler;
using DiLe.Mes.Cloud.Controllers.Abnormal.Dto;
using DiLe.Mes.Cloud.Controllers.Dashboard.Dto;
using DiLe.Mes.Model.Cloud.Dashboard.Statistics;
using DiLe.Mes.Model.Cloud.Statistics;
using DiLe.Mes.Model.Common.Equipment.Entity.Maintenance;
using DiLe.Mes.Model.Common.Equipment.Entity.Manage;
using DiLe.Mes.Model.Common.Equipment.Entity.Repair;
using DiLe.Mes.Model.Common.Equipment.Entity.SparePart;
using DiLe.Mes.Model.Common.Mould.Entity.Info;
using DiLe.Mes.Model.Common.Mould.Entity.Maintenance;
using DiLe.Mes.Service.Dto;
using Microsoft.AspNetCore.Authorization;

namespace DiLe.Mes.Cloud.Controllers.Dashboard {
    /// <summary>
    /// 售服Dashboard
    /// </summary>
    [ApiExplorerSettings(GroupName = ApiCloudGroupConst.Dashboard)]
    public class AfterSaleDashboardController : ApiBaseController {

        private readonly EquipmentManageClient _equipmentclient;
        private readonly EquipmentExjosnHandler _handler;
        private readonly WorkOrderClient _workOrder;

        private readonly EquipmentRepairClient _equipmentRepairClient;
        private readonly EquipmentMaintenanceClient _maintenanceClient;

        private readonly MouldInfoClient _mouldInfoClient;
        private readonly MouldRepairClient _mouldRepairClient;
        private readonly MouldMaintenanceClient _mouldMaintenanceClient;


        private readonly StatisticsClient _statisticsClient;

        private readonly SparePartManageClient _sparePartManageClient;

        private readonly SystemClient _systemClient;
        private readonly OrganizationClient _organizationClient;

        /// <summary>
        /// 售服Dashboard
        /// </summary>
        public AfterSaleDashboardController(EquipmentManageClient equipmentManageClient,
                                             EquipmentExjosnHandler handler,
                                             WorkOrderClient workOrderClient,
                                             MouldInfoClient mouldInfoClient,
                                             EquipmentRepairClient equipmentRepairClient,
                                             EquipmentMaintenanceClient equipmentMaintenanceClient,
                                             MouldRepairClient mouldRepairClient,
                                             MouldMaintenanceClient mouldMaintenanceClient,
                                             StatisticsClient statisticsClient,
                                             SparePartManageClient sparePartManageClient,
                                             SystemClient systemClient,
                                             OrganizationClient organizationClient) {
            _equipmentclient = equipmentManageClient;
            _handler = handler;
            _workOrder = workOrderClient;
            _mouldInfoClient = mouldInfoClient;
            _equipmentRepairClient = equipmentRepairClient;
            _maintenanceClient = equipmentMaintenanceClient;
            _mouldRepairClient = mouldRepairClient;
            _mouldMaintenanceClient = mouldMaintenanceClient;
            _statisticsClient = statisticsClient;
            _sparePartManageClient = sparePartManageClient;
            _systemClient = systemClient;
            _organizationClient = organizationClient;
        }

        /// <summary>
        /// 获取售服Dashboard
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<AfterSaleDashboardDto>> GetAfterSaleDashboard() {
            var dto = new AfterSaleDashboardDto();
            //设备
            var eqList = await _equipmentclient.GetEquipmentInfoListAsync();
            await _handler.FillEquipmentInfoExjosn(eqList);
            var eqIds = eqList.ConvertAll(x => x.Id);
            //设备类型
            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            //设备保养记录
            var mrList = await _maintenanceClient.GetMaintenanceRecordListAsync();
            //设备保养计划
            var planList = await _maintenanceClient.GetMaintenancePlanListAsync();
            //设备注册
            var registerList = await _equipmentclient.GetEquipmentRegisterListAsync(p => eqIds.Contains(p.EquipmentInfoId));

            var infomodels = _equipmentclient.GetEquipmentInfoModelList();
            var dic = GetEquipmentTypeDic(typeList);


            var list = new List<EquipmentInfoDto>();
            foreach (var item in eqList) {
                var v = new EquipmentInfoDto {
                    Equipment = item,
                    EquipmentRegister = registerList.FirstOrDefault(p => p.EquipmentInfoId == item.Id),
                    EquipmentType = typeList.FirstOrDefault(p => p.Id == item.TypeId)
                };
                list.Add(v);
            }
            var (eus, upkeeps) = GetEquipUpkeepStatus(eqList, planList, dic, mrList);
            dto.EquipUpkeepStatus = eus;
            dto.EquipUpkeepTaskStatus = upkeeps;
            dto.EquipUkeepTask = GetEquipUkeepTask(planList, mrList);

            dto.EquipAbnormal = await GetEquipAbnormalAsync(eqList);
            dto.EquipFaultSpread = GetEquipFaultSpread();
            dto.EquipWarning = await GetEquipWarningAsync(dic, infomodels);

            var eqstatistics = await _statisticsClient.GetEquipmentUtilizationRateStatisticsList(p => p.Date == DateTime.Now.Date.AddDays(-1));
            dto.Statistic = await GetEquipmentStatisticAsync(eqList, mrList, planList, eqstatistics);

            //模具
            var mList = await _mouldInfoClient.GetMouldInfoListAsync();
            var mIds = eqList.ConvertAll(x => x.Id);
            //模具类型
            var mtypeIds = mList.Select(x => x.TypeId).Distinct().ToList();
            var mtypeList = await _mouldInfoClient.GetMouldTypeListAsync(p => mtypeIds.Contains(p.Id));

            //模具保养记录
            var mmrList = await _mouldMaintenanceClient.GetMouldMaintenanceRecordListAsync();
            //模具保养计划
            var mplanList = await _mouldMaintenanceClient.GetMouldMaintenancePlanListAsync();

            //开工记录
            var rels = await _workOrder.GetStartWorkRecord2MouldListAsync();
            var mouldCount = rels.Select(x => x.MouldId).Distinct().Count();

            dto.Statistic = await GetMouldStatisticAsync(dto.Statistic, mList, mmrList, mplanList, mouldCount);

            dto.MoldStateArr = await MoldStateArrAsync(mList);
            dto.MoldFaultArr = await GetMoldFaultArrAsync();
            dto.MoldWarningArr = GetMoldWarningArr();

            var (meus, mupkeeps) = GetMouldUpkeepStatus(mList, mplanList, mtypeList, mmrList);
            dto.MouldUpkeepStatus = meus;
            dto.MouldUpkeepTaskStatus = mupkeeps;
            dto.MouldUkeepTask = GetMouldUkeepTask(mplanList);


            return Success(dto);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private async Task<Statistic> GetEquipmentStatisticAsync(List<EquipmentInfoEntity> eqList,
                                                                 List<MaintenanceRecordEntity> maintenances,
                                                                 List<MaintenancePlanEntity> planlist,
                                                                 List<EquipmentStatisticsEntity> eqstatistics) {
            var model = new Statistic();
            //设备
            var eqcount = eqstatistics.Select(x => x.DeviceNo).Distinct().Count();
            model.EquipTotal = $"{eqcount}/{eqList.Count}";
            //设备维修
            var repairrecordList = await _equipmentRepairClient.GetRepairRecordListAsync();
            model.EquipRepair = $"0/{repairrecordList.Count}";
            //设备保养
            model.EquipUpkeep = $"{maintenances.Count}/{planlist.Count}";



            return model;

        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private async Task<Statistic> GetMouldStatisticAsync(Statistic model,
                                                             List<MouldInfoEntity> mList,
                                                             List<MouldMaintenanceRecordEntity> mmrList,
                                                             List<MouldMaintenancePlanEntity> mplanList,
                                                             int mouldCount) {


            //模具
            model.MoldTotal = $"{mouldCount}/{mList.Count}";
            //设备维修
            var mrepairrecordList = await _mouldRepairClient.GetMouldRepairRecordListAsync();
            model.MoldRepair = $"0{mrepairrecordList.Count}";

            //模具保养
            model.MoldUpkeep = $"{mmrList.Count}/{mplanList.Count}";


            return model;

        }
        /// <summary>
        /// 
        /// </summary>
        private static (EquipUpkeepStatus eus, List<UpkeepTaskStatusItem> upkeeps) GetEquipUpkeepStatus(List<EquipmentInfoEntity> infoList,
                                                                                                 List<MaintenancePlanEntity> planList,
                                                                                                 Dictionary<string, List<long>> dic,
                                                                                                 List<MaintenanceRecordEntity> recordList) {
            var list = new List<UpkeepTaskStatusItem>();
            var model = new EquipUpkeepStatus {
                ChartType = "pie",
                Title = $"{infoList.Count}台"
            };
            var arr = new List<DataArrItem>();
            foreach (var item in dic) {
                var infos = infoList.Where(x => item.Value.Contains(x.TypeId)).ToList();
                if (infos.None()) {
                    continue;
                }
                var eqIds = infos.ConvertAll(x => x.Id);
                var plans = planList.Where(x => eqIds.Contains(x.EquipmentId ?? 0)).ToList();
                var count = Math.Round((double)(plans.Count / planList.Count)) * 100;
                var da = new DataArrItem {
                    Data = new List<double> { count },
                    Name = item.Key,
                    Suffix = "%"
                };
                arr.Add(da);
                var records = recordList.Where(x => eqIds.Contains(x.EquipmentId)).ToList();
                var ups = new UpkeepTaskStatusItem {
                    Label = item.Key,
                    Value = $"{records.Count}/{plans.Count}"
                };
                list.Add(ups);
            }
            model.DataArr = arr;
            return (model, list);
        }


        /// <summary>
        /// 
        /// </summary>
        private EquipUkeepTask GetEquipUkeepTask(List<MaintenancePlanEntity> planList, List<MaintenanceRecordEntity> recordList) {
            EquipUkeepTask task = new() {
                TaskTotal = planList.Count,
            };
            var completed = recordList.Count;
            var completed_p = Math.Round((double)completed / planList.Count, 2);
            var chart = new Chart {
                chartType = "pie",
                title = $"{completed_p * 100}%",
            };
            var ucompleted_p = (1 - completed_p) * 100;
            chart.DataArr = new List<DataArrItem> {
                 new DataArrItem { Data = new List<double>{ ucompleted_p } , Name ="未完成", Suffix ="%"},
                 new DataArrItem { Data = new List<double>{ completed_p }, Name ="已完成", Suffix ="%"}
            };
            task.Chart = chart;
            return task;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private async Task<List<EquipAbnormalItem>> GetEquipAbnormalAsync(List<EquipmentInfoEntity> equipmentList) {
            var list = new List<EquipAbnormalItem>();
            PaginationModel page = new PaginationModel {
                PageIndex = 1,
                PageSize = 100,
            };
            var date = DateTime.Now.ToString("yyyy-MM-dd");
            var res = await _statisticsClient.GetAlarmInfoStatisticsPageListAsync(p => p.AbnormalDate == date, page);

            foreach (var data in res.Record) {
                if (data == null || data.AbnormalInfo.IsNullOrEmpty()) {
                    continue;
                }
                var eq = equipmentList.FirstOrDefault(p => p.Code == data.EquipmentCode);
                if (eq == null) {
                    continue;
                }
                var m = new EquipAbnormalItem() {
                    Abnormal = $"{eq.ExtJson["PositionName"]?.ToString()}{data.EquipmentName}{data.AbnormalInfo}",
                    //WarningTime = data!.StartAbnormalTime
                };
                list.Add(m);
            }
            return list;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private List<EquipFaultSpreadItem> GetEquipFaultSpread() {
            var list = new List<EquipFaultSpreadItem>();
            list.Add(new EquipFaultSpreadItem { FaultNum = 0, FaultType = "设备报警", HandleNum = 0 });
            return list;
        }
        #region 设备报警统计
        /// <summary>
        /// 获取设备报警统计表信息
        /// </summary>
        /// <returns></returns>
        private async Task<EquipWarning> GetEquipWarningAsync(Dictionary<string, List<long>> dic, List<EquipmentInfoModel> infos) {
            var dateTimelist = GetCurrentWeekDay();
            var list = new List<DataArrItem>();
            var model = new EquipWarning {
                xAxis = dateTimelist.ConvertAll(x => x.ToString("MM月dd日"))
            };


            var eqa = new DataArrItem { Name = "设备报警总数", Type = "bar" };
            list.Add(eqa);
            var eqah = new DataArrItem { Name = "设备报警处理总数", Type = "bar" };
            list.Add(eqah);
            var querylist = dateTimelist.ConvertAll(x => x.ToString("yyyy-MM-dd"));
            var reps = await _statisticsClient.GetAlarmInfoReportAsync(querylist, AppHelper.QueryOrgId);
            foreach (var date in querylist) {
                var count = reps.Where(x => x.Abnormaldate == date).Sum(x => x.Count);
                eqa.Data.Add(count);
            }



            foreach (var item in dic) {
                var codes = infos.Where(x => item.Value.Contains(x.EquipmentTypeId)).Select(x => x.EquipmentCode).ToList();
                if (codes.None()) {
                    continue;
                }
                var m = new DataArrItem { Name = item.Key, Type = "line", Data = [] };
                foreach (var date in querylist) {
                    var count = reps.Where(x => x.Abnormaldate == date && codes.Contains(x.EquipmentCode)).Sum(p => p.Count);
                    m.Data.Add(count);
                }
                list.Add(m);

            }
            model.dataArr = list;
            return model;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, List<long>> GetEquipmentTypeDic(List<EquipmentTypeEntity> typelist) {
            var dic = new Dictionary<string, List<long>>();
            var temps = typelist.Where(p => p.ParentId == 0).ToList();
            foreach (var item in temps) {
                var items = GetChildEquipmentTypeList(item.Id, typelist);
                if (items.None()) {
                    continue;
                }
                items.Add(item.Id);
                dic[item.Name] = items;
            }
            return dic;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static List<long> GetChildEquipmentTypeList(long parentId, List<EquipmentTypeEntity> typelist) {
            var list = new List<long>();
            var temps = typelist.Where(p => p.ParentId == parentId).ToList();
            foreach (var item in temps) {
                list.Add(item.Id);
                var items = GetChildEquipmentTypeList(item.Id, typelist);
                if (!items.None()) {
                    list.AddRange(items);
                }
            }
            return list;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, List<long>> GetMouldTypeDic(List<MouldTypeEntity> typelist) {
            var dic = new Dictionary<string, List<long>>();
            var temps = typelist.Where(p => p.ParentId == 0).ToList();
            foreach (var item in temps) {
                var items = GetChildMouldTypeList(item.Id, typelist);
                if (items.None()) {
                    continue;
                }
                items.Add(item.Id);
                dic[item.Name] = items;
            }
            return dic;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static List<long> GetChildMouldTypeList(long parentId, List<MouldTypeEntity> typelist) {
            var list = new List<long>();
            var temps = typelist.Where(p => p.ParentId == parentId).ToList();
            foreach (var item in temps) {
                list.Add(item.Id);
                var items = GetChildMouldTypeList(item.Id, typelist);
                if (!items.None()) {
                    list.AddRange(items);
                }
            }
            return list;
        }
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private async Task<List<MoldStateArrItem>> MoldStateArrAsync(List<MouldInfoEntity> mList) {
            var list = new List<MoldStateArrItem>();
            var statusIds = mList.Select(m => m.StatusId).Distinct().ToList();
            var statusList = await _mouldInfoClient.GetMouldStatusListAsync(p => statusIds.Contains(p.Id));
            var maps = mList.GroupBy(m => m.StatusId).Select(p => (p.Key, p.ToList())).ToList();
            foreach (var map in maps) {
                var status = statusList.FirstOrDefault(p => p.Id == map.Key);
                var item = new MoldStateArrItem {
                    MoldState = status?.Name ?? "",
                    MoldNum = map.Item2.Count
                };
                var proportion = Math.Round((double)(item.MoldNum / mList.Count), 2) * 100;
                item.Proportion = $"{proportion}%";
                list.Add(item);
            }
            return list;
        }
        /// <summary>
        /// 模具故障
        /// </summary>
        /// <returns></returns>
        private async Task<List<MoldFaultArrItem>> GetMoldFaultArrAsync() {
            var dataList = await _mouldRepairClient.GetMouldRepairRecordModelListAsync();
            var list = new List<MoldFaultArrItem>();
            var maps = dataList.GroupBy(x => x.FaultTypeName).Select(x => (x.Key, x.ToList())).ToList();

            foreach (var item in maps) {
                var m = new MoldFaultArrItem() {
                    FaultNum = 0,
                    FaultType = item.Key ?? "",
                    HandleNum = 0
                };
                m.FaultNum = item.Item2.Count;
                m.HandleNum = item.Item2.Count(x => x.WorkOrderStatus == "completed");
                list.Add(m);
            }
            return list;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private List<MoldWarningArrItem> GetMoldWarningArr() {
            var list = new List<MoldWarningArrItem>();
            list.Add(new MoldWarningArrItem { Abnormal = "", WarningTime = DateTime.Now.ToString(), WarnType = "模具报警" });
            return list;

        }

        /// <summary>
        /// 模具保养计划
        /// </summary>
        private static (MouldUpkeepStatus eus, List<UpkeepTaskStatusItem> upkeeps) GetMouldUpkeepStatus(List<MouldInfoEntity> infoList,
                                                                                                 List<MouldMaintenancePlanEntity> planList,
                                                                                                 List<MouldTypeEntity> typeList,
                                                                                                 List<MouldMaintenanceRecordEntity> recordList) {
            var list = new List<UpkeepTaskStatusItem>();
            var model = new MouldUpkeepStatus {
                ChartType = "pie",
                Title = $"{infoList.Count}台"
            };
            var arr = new List<DataArrItem>();
            foreach (var item in typeList) {
                var infos = infoList.Where(x => x.TypeId == item.Id).ToList();
                if (infos.None()) {
                    continue;
                }
                var ids = infos.ConvertAll(x => x.Id);
                var plans = planList.Where(x => ids.Contains(x.MouldId)).ToList();
                double count;
                if (plans.None()) {
                    count = 0;
                } else {
                    count = Math.Round(plans.Count / (double)planList.Count * 100, 2);
                }
                var da = new DataArrItem {
                    Data = new List<double> { count },
                    Name = item.Name,
                    Suffix = "%"
                };
                arr.Add(da);
                var records = recordList.Where(x => ids.Contains(x.MouldId)).ToList();
                var ups = new UpkeepTaskStatusItem {
                    Label = item.Name,
                    Value = "0"
                };
                if (plans.Count > 0) {
                    ups.Value = $"{records.Count}/{plans.Count}";
                }

                list.Add(ups);
            }
            model.DataArr = arr;
            return (model, list);
        }


        /// <summary>
        /// 
        /// </summary>
        private static MouldUkeepTask GetMouldUkeepTask(List<MouldMaintenancePlanEntity> planList) {
            MouldUkeepTask task = new() {
                TaskTotal = planList.Count,
            };
            var completed = planList.Count(x => x.Status == true);
            var completed_p = Math.Round((double)completed / planList.Count, 2);
            var chart = new Chart {
                chartType = "pie",
                title = $"{completed_p * 100}%",
            };
            var ucompleted_p = (1 - completed_p) * 100;
            chart.DataArr = new List<DataArrItem> {
                 new DataArrItem { Data = new List<double>{ ucompleted_p } , Name ="未完成", Suffix ="%"},
                 new DataArrItem { Data = new List<double>{ completed_p }, Name ="已完成", Suffix ="%"}
            };
            task.Chart = chart;
            return task;
        }



        /// <summary>
        /// 获取本周的日期
        /// </summary>
        /// <returns></returns>
        private static List<DateTime> GetCurrentWeekDay() {

            // 获取当前日期
            DateTime currentDate = DateTime.Now.Date;

            // 获取当前日期是本周的第几天 (0 表示周日，1 表示周一，以此类推)
            int currentDayOfWeek = (int)currentDate.DayOfWeek;

            // 获取本周的起始日期
            DateTime startDateOfWeek = currentDate.AddDays(-currentDayOfWeek);

            // 获取本周每天的日期
            List<DateTime> daysOfWeek = [];
            for (int i = 0; i < 7; i++) {
                DateTime day = startDateOfWeek.AddDays(i);
                daysOfWeek.Add(day);
            }
            return daysOfWeek;
        }


        #region 设备
        #region 设备在线统计
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<EquipmentOnlineStatisticsModel>> GetEquipmentOnlineStatistics() {
            var model = new EquipmentOnlineStatisticsModel();
            //设备
            var eqList = _equipmentclient.GetEquipmentInfoModelList(AppHelper.QueryOrgId);
            //设备类型
            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            var dic = GetEquipmentTypeDic(typeList);
            var list = new List<StatisticItem>();
            foreach (var item in dic) {
                var count = eqList.Count(p => item.Value.Contains(p.EquipmentTypeId));
                var m = new StatisticItem() {
                    TotalNum = count,
                    Type = item.Key
                };
                list.Add(m);
            }

            var eqstatistics = await _statisticsClient.GetEquipmentUtilizationRateStatisticsList(p => p.Date == DateTime.Now.Date.AddDays(-1));
            var items = new List<EOStatistic>();

            foreach (var eqstat in eqList) {
                var s = eqstatistics.Where(p => p.DeviceNo == eqstat.EquipmentSign).ToList();
                if (s.None()) {
                    continue;
                }
                var item = new EOStatistic() {
                    EquipmentCode = eqstat.EquipmentCode,
                    EquipmentName = eqstat.EquipmentName,
                    EquipmentType = eqstat.EquipmentTypeName,
                    Type = GetTypeName(dic, eqstat.EquipmentTypeId)
                };
                foreach (var si in s) {
                    if (item.OnTime == null) {
                        item.OnTime = si.EquipmentStartTime!.Value.ToString("yyyy-MM-dd HH:mm:dd");
                    } else if (DateTime.Parse(item.OnTime) > si.EquipmentStartTime) {
                        item.OnTime = si.EquipmentStartTime!.Value.ToString("yyyy-MM-dd HH:mm:dd");
                    }
                }
                items.Add(item);
                var m = list.FirstOrDefault(x => x.Type == item.Type);
                if (m != null) {
                    m.OnlineNum += 1;
                }
            }
            model.Data = items;
            list.ForEach(x => x.Value = $"{x.OnlineNum}/{x.TotalNum}");
            model.Statistic = list;
            return Success(model);
        }
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private string GetTypeName(Dictionary<string, List<long>> dic, long typeid) {
            string typename = "";
            foreach (var item in dic) {
                if (item.Value.Contains(typeid)) {
                    typename = item.Key;
                    break;
                }
            }
            return typename;
        }
        #region 设备维修统计
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<EquipmentRepairStatisticsModel>> GetEquipmentRepairStatistics() {
            var model = new EquipmentRepairStatisticsModel();
            //设备
            var eqList = _equipmentclient.GetEquipmentInfoModelList();
            //设备类型
            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            var dic = GetEquipmentTypeDic(typeList);
            var list = new List<StatisticItem>();
            foreach (var item in dic) {
                var count = eqList.Count(p => item.Value.Contains(p.EquipmentTypeId));
                var m = new StatisticItem() {
                    TotalNum = count,
                    Type = item.Key
                };
                list.Add(m);
            }
            var items = new List<EPStatistic>();
            model.RepairData = items;
            model.AlarmData = new List<EAStatistic>();
            list.ForEach(x => x.Value = $"0/{x.TotalNum}");
            model.Statistic = list;
            return Success(model);
        }
        #endregion
        #region 设备保养统计
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<EquipmentMaintenanceStatisticsModel>> GetEquipmentMaintenanceStatistics() {
            var model = new EquipmentMaintenanceStatisticsModel();
            //设备
            var eqList = _equipmentclient.GetEquipmentInfoModelList();
            //设备类型
            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            var dic = GetEquipmentTypeDic(typeList);
            var list = new List<StatisticItem>();
            foreach (var item in dic) {
                var count = eqList.Count(p => item.Value.Contains(p.EquipmentTypeId));
                var m = new StatisticItem() {
                    TotalNum = count,
                    Type = item.Key
                };
                list.Add(m);
            }
            var items = new List<EPlanStatistic>();
            model.PlanData = items;
            model.RecordData = new List<ERecordStatistic>();
            list.ForEach(x => x.Value = $"0/{x.TotalNum}");
            model.Statistic = list;
            return Success(model);
        }
        #endregion
        #endregion
        #region 模具
        /// <summary>
        /// 模具在线统计
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<MouldOnlineStatisticsModel>> GetMouldOnlineStatistics() {
            var model = new MouldOnlineStatisticsModel();
            //模具
            var eqList = await _mouldInfoClient.GetMouldInfoListAsync();
            //模具类型
            var typeList = await _mouldInfoClient.GetMouldTypeListAsync();
            var dic = GetMouldTypeDic(typeList);
            var list = new List<StatisticItem>();
            foreach (var item in dic) {
                var count = eqList.Count(p => item.Value.Contains(p.EquipmentTypeId));
                var m = new StatisticItem() {
                    TotalNum = count,
                    Type = item.Key
                };
                list.Add(m);
            }
            model.Data = new List<MOStatistic>();
            list.ForEach(x => x.Value = $"0/{x.TotalNum}");
            model.Statistic = list;
            return Success(model);
        }
        /// <summary>
        /// 模具维修统计
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<MouldRepairStatisticsModel>> GetMouldRepairStatistics() {
            var model = new MouldRepairStatisticsModel();
            //模具
            var eqList = await _mouldInfoClient.GetMouldInfoListAsync();
            //模具类型
            var typeList = await _mouldInfoClient.GetMouldTypeListAsync();
            var dic = GetMouldTypeDic(typeList);
            var list = new List<StatisticItem>();
            foreach (var item in dic) {
                var count = eqList.Count(p => item.Value.Contains(p.EquipmentTypeId));
                var m = new StatisticItem() {
                    TotalNum = count,
                    Type = item.Key
                };
                list.Add(m);
            }
            var items = new List<MPStatistic>();
            model.RepairData = items;
            model.ReportRepairData = new List<MRStatistic>();
            list.ForEach(x => x.Value = $"0/{x.TotalNum}");
            model.Statistic = list;
            return Success(model);
        }
        /// <summary>
        /// 设备保养统计
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<MouldMaintenanceStatisticsModel>> GetMouldMaintenanceStatistics() {
            var model = new MouldMaintenanceStatisticsModel();
            //模具
            var eqList = await _mouldInfoClient.GetMouldInfoListAsync();
            //模具类型
            var typeList = await _mouldInfoClient.GetMouldTypeListAsync();
            var dic = GetMouldTypeDic(typeList);
            var list = new List<StatisticItem>();
            foreach (var item in dic) {
                var count = eqList.Count(p => item.Value.Contains(p.EquipmentTypeId));
                var m = new StatisticItem() {
                    TotalNum = count,
                    Type = item.Key
                };
                list.Add(m);
            }
            var items = new List<MPlanStatistic>();
            model.PlanData = items;
            model.RecordData = new List<MRecordStatistic>();
            list.ForEach(x => x.Value = $"0/{x.TotalNum}");
            model.Statistic = list;
            return Success(model);
        }
        #endregion

        #region  DataV
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet, AllowAnonymous]
        public async Task<ApiResult<DataVInfoDto>> GetDataVInfo() {
            var dto = new DataVInfoDto();
            //设备信息
            var eqinfolist = await _equipmentclient.GetEquipmentInfoModelListAsync(AppHelper.QueryOrgId);

            //设备类型
            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            var dic = GetEquipmentTypeDic(typeList);
            //维修
            var recordList = await _equipmentRepairClient.GetRepairRecordListAsync();
            dto.RepairCompleteChart = GetRepairCompleteChart(recordList);
            //异常报警
            dto.AbnormalInfos = await GetAbnormalInfoList(typeList, eqinfolist, recordList);
            dto.WarningRunChart = await GetEquipWarningRunChartAsync(dic, eqinfolist);
            //设备数量
            dto.EquipmentNumberChart = GetEquipmentNumberChart(dic, eqinfolist);
            //
            dto.SparePartUseChart = await GetSparePartUseChartAsync();
            return Success(dto);
        }
        /// <summary>
        /// 获取设备报警推移图
        /// </summary>
        /// <returns></returns>
        private async Task<EquipWarning> GetEquipWarningRunChartAsync(Dictionary<string, List<long>> dic, List<EquipmentInfoModel> infos) {
            var dateTimelist = GetCurrentWeekDay();
            var list = new List<DataArrItem>();
            var model = new EquipWarning {
                xAxis = dateTimelist.ConvertAll(x => x.ToString("MM月dd日"))
            };


            var eqa = new DataArrItem { Name = "设备报警总数", Type = "bar" };
            list.Add(eqa);
            var eqah = new DataArrItem { Name = "设备报警处理总数", Type = "bar" };
            list.Add(eqah);
            var querylist = dateTimelist.ConvertAll(x => x.ToString("yyyy-MM-dd"));
            var reps = await _statisticsClient.GetAlarmInfoReportAsync(querylist, AppHelper.QueryOrgId);
            foreach (var date in querylist) {
                var count = reps.Where(x => x.Abnormaldate == date).Sum(x => x.Count);
                eqa.Data.Add(count);
            }
            foreach (var item in dic) {
                var codes = infos.Where(x => item.Value.Contains(x.EquipmentTypeId)).Select(x => x.EquipmentCode).ToList();
                if (codes.None()) {
                    continue;
                }
                var m = new DataArrItem { Name = item.Key, Type = "line", Data = [] };
                foreach (var date in querylist) {
                    var count = reps.Where(x => x.Abnormaldate == date && codes.Contains(x.EquipmentCode)).Sum(p => p.Count);
                    m.Data.Add(count);
                }
                list.Add(m);

            }
            model.dataArr = list;
            return model;
        }


        /// <summary>
        /// 获取设备异常
        /// </summary>
        /// <returns></returns>
        private async Task<List<AbnormalInfo>> GetAbnormalInfoList(List<EquipmentTypeEntity> typeList, List<EquipmentInfoModel> eqinfolist, List<RepairRecordEntity> recordList) {
            var list = new List<AbnormalInfo>();
            //类型
            var typeids = eqinfolist.ConvertAll(x => x.EquipmentTypeId);
            //位置
            var positionIds = eqinfolist.Where(x => x.PositionId != null).Select(p => p.PositionId).Distinct().ToList();
            var positionList = await _systemClient.GetPositionListAsync(p => positionIds.Contains(p.Id));
            //工厂
            var factoryIds = eqinfolist.Where(x => x.FactoryId != null).Select(p => p.FactoryId).Distinct().ToList();
            var factoryList = await _organizationClient.GetOrganizationListAsync(p => factoryIds.Contains(p.Id));
            //设备报警信息
            var ruleList = await _equipmentclient.GetAbnormalAlarmRuleListAsync(p => typeids.Contains(p.EquipmentTypeId));
            var whereExpression = Expressionable.Create<AlarmInfoStatisticsEntity>();
            whereExpression.And(x => x.EndAbnormalTime == null);
            whereExpression.And(x => x.FactoryId == AppHelper.QueryOrgId);
            var reslist = await _statisticsClient.GetAlarmInfoStatisticsListAsync(whereExpression.ToExpression());
            reslist = reslist != null ? [.. reslist?.OrderByDescending(x => x.AbnormalDate)] : [];
            foreach (var item in reslist) {
                var info = eqinfolist.FirstOrDefault(i => i.EquipmentCode == item.EquipmentCode);
                if (info == null) {
                    continue;
                }
                var rule = ruleList?.FirstOrDefault(x => x.EquipmentTypeId == info.EquipmentTypeId && x.AlarmName == item.AbnormalInfo);
                if (rule == null) {
                    continue;
                }
                var type = typeList?.FirstOrDefault(x => x.Id == info.EquipmentTypeId);

                var im = item.Adapt<AbnormalInfo>();
                im.Position = rule?.Position ?? "";
                im.FileId = type?.FileId ?? "";
                im.AbnormalLevel = rule?.AlarmLevel ?? 0;
                im.RepairRecordId = recordList?.FirstOrDefault(x => x.FaultId == item.Id)?.Id ?? 0;
                //设备信息
                im.EquipmentTypeName = type?.Name ?? "";
                im.EquipmentSpecification = info.Specification;
                im.EquipmentPositionName = positionList?.FirstOrDefault(x => x.Id == info.PositionId)?.Position;
                im.EquipmentFactoryName = factoryList?.FirstOrDefault(x => x.Id == info.FactoryId)?.Name;
                im.EquipmentId = info.EquipmentId;
                list.Add(im);
            }
            return list;
        }

        /// <summary>
        /// 获取设备数量
        /// </summary>
        /// <returns></returns>
        private EquipmentNumberChart GetEquipmentNumberChart(Dictionary<string, List<long>> dic, List<EquipmentInfoModel> eqinfolist) {

            var model = new EquipmentNumberChart {
                ChartType = "pie",
                Title = $"{eqinfolist.Count}台"
            };
            var arr = new List<DataArrItem>();
            foreach (var type in dic) {
                var count = eqinfolist.Count(x => type.Value.Contains(x.EquipmentTypeId));
                var da = new DataArrItem {
                    Data = [count],
                    Name = type.Key,
                    Suffix = "%"
                };
                arr.Add(da);
            }
            model.DataArr = arr;
            return model;
        }


        /// <summary>
        /// 获取维修信息
        /// </summary>
        /// <returns></returns>
        private Chart GetRepairCompleteChart(List<RepairRecordEntity> recordList) {

            var completed = recordList.Count(p => p.WorkOrderStatus == "completed");
            var completed_p = Math.Round((double)completed / recordList.Count, 2);
            var chart = new Chart {
                chartType = "pie",
                title = "维修信息",
            };
            var ucompleted_p = (double)(1 - (decimal)completed_p) * 100;
            chart.DataArr = [
                 new DataArrItem { Data = [ucompleted_p] , Name ="未完成", Suffix ="%" ,Type="pie"},
                 new DataArrItem { Data = [completed_p * 100], Name ="已完成", Suffix ="%",Type="pie"}
            ];

            return chart;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private async Task<SparePartUseChart> GetSparePartUseChartAsync() {

            var list = new List<DataArrItem>();
            var model = new SparePartUseChart {
                xAxis = ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
            };
            DateTime start = DateTime.Now.FirstDayOfYear();
            DateTime end = DateTime.Now.LastDayOfYear();
            var whereExpression = Expressionable.Create<SparePartStockOutEntity>();
            whereExpression.And(x => x.StockOutDateTime >= start);
            whereExpression.And(x => x.StockOutDateTime <= end);

            var stockOutRecords = await _sparePartManageClient.GetSparePartStockOutListAsync(whereExpression.ToExpression());
            var ids = stockOutRecords.ConvertAll(p => p.Id);
            var rels = await _sparePartManageClient.GetStockOutSparePartList(p => ids.Contains(p.StockOutId));

            var m = new DataArrItem { Name = "备件使用情况", Type = "line", Data = [] };
            for (int i = 0; i < 12; i++) {
                var date = start.AddMonths(i);
                DateTime i_start = date.FirstDayOfMonth();
                DateTime i_end = date.LastDayOfMonth();

                var recordIds = stockOutRecords.Where(x => x.StockOutDateTime >= i_start && x.StockOutDateTime <= i_end).Select(p => p.Id).ToList();

                var stockoutnumber = rels?.Where(p => recordIds.Contains(p.StockOutId)).Sum(p => p.StockOutNumber);

                m.Data.Add(stockoutnumber ?? 0);
            }
            list.Add(m);
            model.dataArr = list;
            return model;
        }


        #endregion
    }
}
